/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sistemasdistribuidos.pedido;

import java.io.*;
import java.net.*;
import java.util.Arrays;

/**
 * Servidor com threads por pedido. As threads são criadas assim que os
 * pedidos são feitos. A thread criada processa o pedido, responde ao cliente e
 * é finalizada, mas a conexão continua ativa.
 *
 * @author Manoel Afonso Filho
 */
public class Servidor extends Thread {

    private Socket socketCliente;

    public Servidor(Socket socket) {
        this.socketCliente = socket;
    }

    @Override
    public void run() {
        ObjectOutputStream saida;
        ObjectInputStream entrada;
        
        try {
            //Inicia o ordenamento do vetor de um cliente.
            System.out.println(this.getName() + " conectada a um cliente.");

            //Obtém os fluxos de entrada e saída.            
            saida = new ObjectOutputStream(socketCliente.getOutputStream());
            saida.flush();
            entrada = new ObjectInputStream(socketCliente.getInputStream());
            
            //Aguarda até que o cliente envie um pedido.
            entrada.read();

            //Lê o objeto enviado pelo cliente.
            Object obj = entrada.readObject();
            
            if (!(obj instanceof String)) {
                //Ordena o vetor do cliente.
                int[] arr = (int[]) obj;
                Arrays.sort(arr);
                //Simula um processamento demorado.
                Thread.sleep(5000);
                //Envia o vetor ordenado.
                System.out.println(this.getName() + " enviando array ordenado.");
                enviarMensagem(arr, saida);
            }

        } catch (IOException | ClassNotFoundException | InterruptedException ex) {
            System.err.println("Erro: " + ex);
        }
    }

    /**
     * Envia um objeto para o cliente.
     *
     * @param msg Objeto a ser enviado.
     */
    private void enviarMensagem(Object msg, ObjectOutputStream saida) {
        try {
            saida.writeObject(msg);
            saida.flush();
        } catch (IOException ex) {
            System.err.println("Erro ao enviar \"" + msg + "\" : " + ex);
        }
    }

    /**
     * Cria o servidor.
     *
     * @param args
     * @throws IOException
     */
    public static void main(String args[]) throws IOException {
        System.out.println("Iniciando servidor com threads por pedido*.");
        
        ServerSocket socketServidor = new ServerSocket(2004);
        System.out.println("Servidor aguardando conexões.");
        //Aguarda uma conexão.
        Socket socketCliente = socketServidor.accept();
        
        while (true) {
            //Cria uma thread para gerenciar os pedidos do cliente.
            Servidor servidor = new Servidor(socketCliente);
            servidor.start();
            //Aguarda outra conexão para criar outra thread.
            socketCliente = socketServidor.accept();
        }
    }
}